package com.game.modular.game.battle.panel.attribute.domain;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;

import java.io.Serializable;
import java.util.*;

import com.game.comment.exection.PlannerException;
import com.game.comment.util.BeanUtil;
import com.game.modular.game.battle.panel.Battle;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.extern.slf4j.Slf4j;

import javax.validation.constraints.NotNull;

import static com.game.modular.game.battle.info.FiledName.eventMap;
import static com.game.modular.game.battle.info.FiledName.phaseMap;

/**
 * 武将属性
 *
 * @author cxy
 * @since 2024-08-23 19:46:19
 */
@Slf4j
@ApiModel("武将属性")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class PlayerHeroAttribute implements Serializable {
    ///////////////////////////////////////////////////////////////////////////////////////////////////////// 生成实体字段
    @TableId(type = IdType.INPUT)
    @ApiModelProperty("主键")
    private Long id;
    @ApiModelProperty("0:防守,1:进攻")
    private Integer rankCamp;


    @ApiModelProperty("武将id")
    private Long playerHeroId;

    @ApiModelProperty("战斗id")
    private Long battleId;

    @ApiModelProperty("回合累计攻击次数")
    private Integer attackCount1;

    @ApiModelProperty("回合累计普通攻击次数")
    private Integer attackCount2;

    @ApiModelProperty("回合累计物理攻击次数")
    private Integer attackCount3;

    @ApiModelProperty("回合累计策略攻击次数")
    private Integer attackCount4;

    @ApiModelProperty("武力")
    private Double att;

    @ApiModelProperty("防御")
    private Double def;

    @ApiModelProperty("策略")
    private Double magic;

    @ApiModelProperty("先攻值")
    private Double speed;

    @ApiModelProperty("统帅")
    private Double des;

    @ApiModelProperty("兵力")
    private Long currentForce;

    @ApiModelProperty("所有伤害")
    private Double all1 = 0.0;
    private Double all0 = 0.0;

    @ApiModelProperty("造成普通攻击伤害")
    private Double attack1 = 0.0;
    @ApiModelProperty("受到普通攻击伤害")
    private Double attack0 = 0.0;

    @ApiModelProperty("物理伤害")
    private Double physics1 = 0.0;
    private Double physics0 = 0.0;

    @ApiModelProperty("策略伤害")
    private Double strategy1 = 0.0;
    private Double strategy0 = 0.0;

    @ApiModelProperty("恢复率")
    private Double recover1 = 0.0;// 造成的恢复
    private Double recover0 = 0.0;// 受到的恢复

    @ApiModelProperty("主动战法")//
    private Double activeIncrease1 = 0.0;
    private Double activeIncrease0 = 0.0;

    @ApiModelProperty("上回合死亡兵力")
    private double lastDeadForces = 0.0;

    @ApiModelProperty("前回合死亡兵力")
    private double currentDeadForces = 0.0;

    @ApiModelProperty("无视防御效果")
    private Double igDefensiveDefense = 0.0;

    @ApiModelProperty("无视策略防御效果")
    private Double igStrategicDefense = 0.0;

    @ApiModelProperty("无视物理防御效果")
    private Double igPhysicalDefense = 0.0;

    //////////////////////////////////////////////// 状态面板
    @ApiModelProperty("当前拥有的免疫")
    public Map<Long, Integer> immune = new HashMap<>();

    private static final String VALUE_STATUS_KEY = "技能类型:%d--技能效果类型";
    @ApiModelProperty("数值类效果")
    private Map<String, ValueStatus> valueStatus = new HashMap<>();

    @ApiModelProperty("当前拥有的效果")
    private Map<Long, EffectStatus> status = new HashMap<>();

    @ApiModelProperty("当前所处阶段")
    private Integer phase;
    /**
     * key: 技能类型
     * value: 暂定
     */
    @ApiModelProperty("当前所处事件")// 这里指技能
    public Map<Integer, String> event = new HashMap<>();
    @ApiModelProperty("行为")// 效果
    public Map<Long, Object> behaviorMap = new HashMap<>();

    @ApiModelProperty("受到的技能效果")
    private Long skillEffectTypeId;
    @ApiModelProperty("效果是否产生结果")
    private Integer effectIsActive;

    @ApiModelProperty("上回合死亡数量")
    private Long lastDead;
    private Long thisDead;

    @ApiModelProperty("队伍位置")
    private Integer rankOrder;

    @ApiModelProperty("战斗技能次数")
    private Map<Long, Integer> skillBattleCount = new HashMap<>();
    private Map<Long, Integer> skillRoundCount = new HashMap<>();

    public Double obtainPhysicsAttackIncrease() {
        return physics1 + all1;
    }

    public Double obtainPhysicsAttackDecrease() {
        return physics0 + all0;
    }

    public Double obtainStrategyAttackIncrease() {
        return strategy1 + all1;
    }

    public Double obtainStrategyAttackDecrease() {
        return strategy0 + all0;
    }

    public Double obtainRecoverIncrease() {
        return recover1;
    }

    public Double obtainRecoverDecrease() {
        return recover0;
    }


    /**
     * 改变属性
     */
    public void attributeUpdate(
            @NotNull(message = "字段名") String fieldName,
            @NotNull(message = "变动值") Object value,
            @NotNull(message = "1:造成 0:受到") Integer direction,
            @NotNull(message = "成功") Integer isSuccessful,
            @NotNull(message = "效果原因") Long effectTypeId
    ) {
        if (fieldName.isEmpty()) {
            throw new PlannerException("技能效果字段名为空");
        }
        if (direction == 1) {// 造成
            long behave = effectTypeId + 100L;
            behaviorMap.put(behave, 0);
            if (isSuccessful == 1) {
                behaviorMap.put(behave, value);
            }
        } else { // 受到
            long behave = -effectTypeId - 100L;
            behaviorMap.put(behave, 0);
            if (isSuccessful == 1) {
                behaviorMap.put(behave, value);
                BeanUtil.updateField(this, fieldName, value);
            }
        }

    }

    /**
     * 刷新回合信息
     */
    public void refreshRoundInfo() {
        Battle battle = Battle.get(battleId);
        Integer round = battle.getRound();
        status.forEach((k, v) -> v.refreshStatus(round));
        valueStatus.forEach((k, v) -> v.refreshStatus(round));
        skillRoundCount.forEach((k, v) -> skillRoundCount.put(k, 0));
        lastDead = thisDead;
        thisDead = 0L;
    }

    public void logSkillCount(Long coreSkillStarId) {
        boolean b = skillBattleCount.containsKey(coreSkillStarId);
        if (b) {
            skillBattleCount.put(coreSkillStarId, skillBattleCount.get(coreSkillStarId) + 1);
        } else {
            skillBattleCount.put(coreSkillStarId, 1);
        }
        boolean b1 = skillRoundCount.containsKey(coreSkillStarId);
        if (b1) {
            skillRoundCount.put(coreSkillStarId, skillRoundCount.get(coreSkillStarId) + 1);
        } else {
            skillRoundCount.put(coreSkillStarId, 1);
        }
    }

    public void logPhase() {
        log.info("-------------------------{}-{}:{}阶段-------------------------",
                playerHeroId, phase, phaseMap.get(phase)
        );
    }


    /**
     * 清除行为
     */
    public void clearAction() {
        behaviorMap = new HashMap<>();
        behaviorMap = new HashMap<>();
        phase = 0;
    }
}